package messageservice

import (
	"log"

	"github.com/gomodule/redigo/redis"
)

/**
	The Do method converts command arguments to bulk strings for transmission to the server as follows:

	Go Type                 Conversion
	[]byte                  Sent as is
	string                  Sent as is
	int, int64              strconv.FormatInt(v)
	float64                 strconv.FormatFloat(v, 'g', -1, 64)
	bool                    true -> "1", false -> "0"
	nil                     ""
	all other types         fmt.Fprint(w, v)
	Redis command reply types are represented using the following Go types:

	Redis type              Go type
	error                   redis.Error
	integer                 int64
	simple string           string
	bulk string             []byte or nil if value not present.
	array                   []interface{} or nil if value not present.
**/

var RedisAddress = "127.0.0.1:6379"

type RedisClient struct {
	Address string
	Client  redis.Conn
}

func (p *RedisClient) Connect(address string) {
	if p.Client == nil {
		if address != "" {
			var err error
			p.Client, err = redis.Dial("tcp", address)
			p.Address = address
			if err != nil {
				panic("redis连接失败")
			}
			return
		}
		var err error
		p.Client, err = redis.Dial("tcp", RedisAddress)
		p.Address = RedisAddress
		if err != nil {
			panic("redis连接失败")
		}
	}
}
func (p *RedisClient) Close() bool {
	err := p.Client.Close()
	if err != nil {
		log.Println("关闭REDIS连接错误", err)
		return false
	}
	p.Client = nil
	return true
}
func (p *RedisClient) Del(name string) bool {
	p.Connect(p.Address)
	rp, err := p.Client.Do("del", name)
	if err != nil {
		log.Println("del 错误", err)
		return false
	}
	log.Println("redis del结果", rp)
	return true
}
func (p *RedisClient) Get(name string) string {
	p.Connect(p.Address)
	if name == "" {
		return ""
	}
	rp, err := p.Client.Do("get", name)
	if err != nil {
		log.Println("set 错误", err)
		return ""
	}
	log.Println("redis get结果", name, string(rp.([]byte)))
	if rp == nil {
		return ""
	}
	return string(rp.([]byte))
}

// px 空字符串为不设置有效期
func (p *RedisClient) Set(name string, val string, px string) string {
	p.Connect(p.Address)
	if name == "" {
		return ""
	}
	if px != "" {
		rp, err := p.Client.Do("set", name, val, "PX", px)
		if err != nil {
			log.Println("redis set 错误", err)
			return ""
		}
		log.Println("redis set结果", rp)
		return rp.(string)
	} else {
		rp, err := p.Client.Do("set", name, val)
		if err != nil {
			log.Println("set 错误", err)
			return ""
		}
		log.Println("redis set结果", rp)
		return rp.(string)
	}
}

// 添加成员到组
func (p *RedisClient) GroupSet(groupname string, member string) bool {
	p.Connect(p.Address)
	rp, err := p.Client.Do("SADD", groupname, member)
	if err != nil {
		log.Println("SADD 错误", err)
		return false
	}
	log.Println("redis SADD 结果", rp)
	if rp != nil && rp.(int64) > 0 {
		return true
	}
	return false
}

// 删除组中成员
func (p *RedisClient) GroupDel(groupname string, member string) bool {
	p.Connect(p.Address)
	rp, err := p.Client.Do("SREM", groupname, member)
	if err != nil {
		log.Println("SREM 错误", err)
		return false
	}
	log.Println("redis SREM 结果", rp)
	if rp != nil && rp.(int64) > 0 {
		return true
	}
	return false
}

// 返回组成员
func (p *RedisClient) GroupList(groupname string) []string {
	p.Connect(p.Address)
	rp, err := p.Client.Do("SMEMBERS", groupname)
	if err != nil {
		log.Println("SMEMBERS 错误", err)
		return []string{}
	}
	if rp != nil {
		list := rp.([]interface{})
		log.Println(groupname, "结果", rp)
		data := make([]string, len(list))
		for i, v := range list {
			if v != nil {
				data[i] = string(v.([]byte))
			}
		}
		return data
	}
	return []string{}
}

// 1 用户id 存储该用户所在节点RPC地址
const RD_USER_RPCNODE = "user:%s"

// 1 群组名称 组里面保存的是成员，集合
const RD_GROUP_MEMBERS = "group:%s"
